今天這篇要來介紹開發 ROS 專案中的非常重要的一環,也就是 ROS 的通訊方式:話題(Topic)和服務(Service)。
在 ROS 中,訊息(Message)是節點之間互相傳遞資訊的資料結構,訊息透過兩種管道來傳遞:話題(Topics)和服務(Services),各自適用於不同的通訊情境。
在話題(Topic)這個管道中,一個節點傳遞訊息到某個話題上稱為「發布(Publish)」,而其他節點接收這個話題的訊息則是「訂閱(Subscribe)」。話題的通訊方式有點像是一個「討論版」,任何人都能在這個版上發布文章,而訂閱這個版的人可以隨時查看文章內容。在 ROS 的情境中,會稱傳遞訊息的節點為「發布者(Publisher)」,訂閱訊息的節點則是「訂閱者(Subscriber)」。
就像討論版上的發布者通常不知道、不在乎誰正在查看文章,反正文章發出去就沒有他的事了,會看到的人自然就會看到。而 ROS 話題也是一樣,發布者節點也不需要關心其他節點的狀態,它只管發布訊息話題上,其他訂閱者節點就會自己接收到。
這種模式屬於異步通訊機制,適合用於持續傳輸資訊流的情況,像是傳遞和監聽感測器的測量數據。
服務(Services)與話題不同,服務傳遞的訊息裡會包含一個「請求(Request)」和一個「回應(Reply)」 ,提供服務的節點被稱為 「服務代理(Service Proxy)」。
服務的通訊方式比較像是「餐廳點菜」,服務生會提供點餐服務,客人必須先呼喚服務生才可以點餐。同樣在 ROS 服務中,當一個服務代理提供了一個服務,而另一個節點需要這個服務時,節點需要向服務代理發送請求並等待回應。
服務屬於同步通訊機制,通常用在需要即時回應的操作,例如無人機起飛降落、保存資料或改變系統狀態。
在繼續介紹話題和服務的指令之前,我還要先介紹一下 rqt 這個圖形介面工具。
rqt 是基於 Qt 框架開發的圖形介面工具。最常使用的是 rqt_graph
,它會以圖形方式顯示所有運行中的節點以及它們之間的通訊連接(包含話題和服務)。
使用以下指令開啟:
$ rosrun rqt_graph rqt_graph
例如,在上一篇使用 TurtleSim 套件的鍵盤控制模組時,同時也開啟 rqt_graph
就可以看到以下的圖形:
在 rqt_graph
生成的圖中,圓圈代表節點,箭頭則表示話題或服務的資料流向,方框是話題或服務名稱。
在下面這張圖裡包含以下資訊:
/teleop_turtle
:
這個節點是由 rosrun turtlesim turtle_teleop_key
指令啟動的。它負責接收你的鍵盤輸入並將這些輸入轉換成速度指令。
/turtlesim
:
這是 TurtleSim 套件的主要節點,負責模擬烏龜的行為。
箭頭和方框:
箭頭從 /teleop_turtle
指向 /turtlesim
,表示速度的指令是由 /teleop_turtle
發布到 /turtle1/cmd_vel
這個話題,然後被 /turtlesim
訂閱和接收。
顏色:
在 rqt_graph
的預設狀態下,紅色代表當前滑鼠懸停的物件( 節點、話題或是服務),藍色代表資料流的來處,綠色代表資料流的去處。
由於 ROS 的訊息分成話題和服務這兩種傳遞管道,它們相關的 ROS 命令列工具使用方式也不太一樣。
下一篇就會來介紹如何使用 ROS 命令列工具來讓節點發送和接收訊息,並且透過指令來控制 TurtleSim 的烏龜。